home *** CD-ROM | disk | FTP | other *** search
- /* ExternalCheckIn.c: External CheckIn applet for ProjectDrag
- *
- * A set of applets for drag and drop source control by Tim Maroney.
- * See develop, issue 23 for details.
- *
- * Built on DropShell by Leonard Rosenthol, Stephan Somogyi, and Marshall Clow,
- * and using the MoreFiles utilities by Jim Luther.
- *
- * This software is free, but don't modify and redistribute it without
- * changing the status window to indicate your name and your changes!
- */
-
-
- #include <Errors.h>
- #include <StandardFile.h>
-
- #include "DSUserProcs.h"
- #include "SourceServer.h"
- #include "PDUtilities.h"
- #include "PDDialogs.h"
- #include "Comments.h"
- #include "FileCancel.h"
- #include "TasksAndErrors.h"
- #include "FileCopy.h"
-
-
- void ExternalCheckInFile(FSSpec *file);
-
-
- /* This routine is called for each file passed in the ODOC event. */
-
- pascal void OpenDoc ( FSSpecPtr myFSSPtr, Boolean opening, Handle userDataHandle )
- {
- #pragma unused ( opening )
- #pragma unused ( userDataHandle )
-
- ExternalCheckInFile(myFSSPtr);
- }
-
-
-
- /* filter files based on (file NOT original) AND (file.name IS original.name) */
-
- pascal Boolean FindTargetFileFilter(CInfoPBPtr pb, Ptr myDataPtr)
- {
- FSSpecPtr theFile = (FSSpecPtr)myDataPtr;
- Boolean display = false;
- /* XXX make sure it has a CKID */
- if (pb->hFileInfo.ioVRefNum != theFile->vRefNum
- || pb->hFileInfo.ioFlParID != theFile->parID)
- display = EqualString(theFile->name, pb->hFileInfo.ioNamePtr, false, false);
- return !display;
- }
-
-
- void ExternalCheckInFile(FSSpec *file)
- {
- Str63 userName;
- Str15 nickname;
- Str255 comment;
- AEDesc command;
- Str255 projectName;
- OSErr err;
- CKIDHandle theCKID;
- FSSpec targetFile;
- FSSpec targetFolder;
-
- TaskStart(2001, 1, file->name, NULL, NULL, NULL); /* checking in */
-
- /* find the user name and initials */
- err = GetUserSettings(userName, nickname, false);
- if (err != noErr)
- {
- gDone = true;
- return;
- }
-
- /* get the target file with Standard File */
- {
- StandardFileReply reply;
- Str255 prompt;
- Point where;
- OSErr err;
- FInfo info;
-
- /* must be the same type */
- err = FSpGetFInfo(file, &info);
- if (err != noErr)
- {
- RaiseErrorNumber(err);
- return;
- }
-
- SetPt(&where, -1, -1);
- ReplaceInIndString(prompt, 2002, 1, file->name, NULL, NULL, NULL);
- ParamText(prompt, NULL, NULL, NULL);
- CustomGetFile (FindTargetFileFilter, 1, &info.fdType, &reply, kSelectWithPromptDialog, where,
- NULL, NULL, NULL, NULL, (Ptr)file);
- if (!reply.sfGood)
- {
- RaiseErrorNumber(userCanceledErr);
- return;
- }
- targetFile = reply.sfFile;
- }
-
- /* get the CKID */
- err = ExtractCKID(&targetFile, &theCKID);
- if (err != noErr)
- {
- RaiseErrorNumber(err);
- return;
- }
-
- /* mount the project */
- err = MountProjectFromCKID(theCKID, projectName);
- if (err != noErr)
- {
- DisposeHandle((Handle)theCKID);
- return;
- }
-
- /* Make sure the file is writeable. */
- if (!(*theCKID)->writeable && !(*theCKID)->modifyReadOnly)
- {
- /* check out the file */
- TaskStart(2001, 2, file->name, NULL, NULL, NULL); /* checking out */
-
- /* create a CheckOut -m command for SourceServer
- * CheckOut -m -cs <comment> -d <dir> -project <project> -u <user> <file>
- */
- err = CreateCommand(&command, "CheckOut");
- if (err == noErr)
- err = AddCStringArg(&command, "-m");
- if (err == noErr)
- err = AddCommentArg(&command, comment);
- if (err == noErr)
- err = AddDirArg(&command, targetFile.vRefNum, targetFile.parID);
- if (err == noErr)
- err = AddProjectArg(&command, projectName);
- if (err == noErr)
- err = AddUserArg(&command, userName);
- if (err == noErr)
- err = AddPStringArg(&command, targetFile.name);
- if (err != noErr)
- {
- AEDisposeDesc(&command);
- RaiseErrorNumber(err);
- return;
- }
-
- err = SendCommand(&command); /* send the command to SourceServer */
- if (err != noErr) return;
- TaskDone();
-
- /* refetch the CKID */
- DisposeHandle((Handle)theCKID);
- theCKID = NULL;
- err = ExtractCKID(&targetFile, &theCKID);
- if (err != noErr)
- {
- RaiseErrorNumber(err);
- return;
- }
- }
- else
- {
- /* XXX -- ask about discarding changes */
- }
-
- /* copy or move the external file in place of the target */
- TaskStart(2001, 3, file->name, NULL, NULL, NULL); /* copying */
-
- /* XXX move the file to the trash instead of deleting it, and restore it
- * to its place on error...
- */
- err = FSpDelete(&targetFile);
- if (err != noErr) goto CancelCheckout;
-
- targetFolder = targetFile;
- targetFolder.name[0] = 0;
- err = FSpFileCopy(file, &targetFolder, NULL, NULL, 0, true);
- if (err != noErr) goto CancelCheckout;
- TaskDone();
-
- /* transfer the CKID into the (new) target file */
- {
- /* open the resource file */
- CKIDHandle otherCKID;
- short refNum = FSpOpenResFile(&targetFile, fsRdWrPerm);
- if (refNum < 0) goto CancelCheckout;
-
- /* get the CKID from it and delete it (if any) */
- otherCKID = (CKIDHandle) Get1IndResource('ckid', 1);
- if (otherCKID != NULL)
- RemoveResource((Handle)otherCKID);
-
- /* add the CKID */
- otherCKID = theCKID;
- err = HandToHand(&(Handle)otherCKID);
- if (err != noErr)
- {
- CloseResFile(refNum);
- goto CancelCheckout;
- }
- AddResource((Handle)otherCKID, 'ckid', 128, "\p");
- err = ResError();
- if (err != noErr)
- {
- DisposeHandle((Handle)otherCKID);
- CloseResFile(refNum);
- goto CancelCheckout;
- }
-
- /* close the resource file */
- CloseResFile(refNum);
- }
-
- /* add the change comment to the file header */
- comment[0] = 0;
- err = AddCheckinComment(file, userName, nickname, comment);
- if (err != noErr) goto CancelCheckout;
-
- /* create a CheckIn command for SourceServer
- * CheckIn -cs <comment> -project <project> -u <user> <file>
- */
- err = CreateCommand(&command, "CheckIn");
- if (err == noErr)
- err = AddCommentArg(&command, comment);
- if (err == noErr)
- err = AddProjectArg(&command, projectName);
- if (err == noErr)
- err = AddUserArg(&command, userName);
- if (err == noErr)
- err = AddFileNameArg(&command, &targetFile);
- if (err != noErr)
- {
- AEDisposeDesc(&command);
- goto CancelCheckout;
- }
-
- err = SendCommand(&command); /* send the command to SourceServer */
- if (err != noErr) goto CancelCheckout;
- TaskDone();
- return;
-
- CancelCheckout:
- /* pop the current task and start a new one if user confirms cancel */
- if (!ResTextYesNo(kProjectDragStrings, kExternalCheckinFailedCancel,
- file->name, NULL, NULL, NULL))
- {
- DisposeHandle((Handle)theCKID);
- RaiseErrorNumber(userCanceledErr);
- return;
- }
-
- TaskDone(); /* not really! */
- TaskStart(2001, 4, targetFile.name, NULL, NULL, NULL); /* canceling */
- err = FileCancel(&targetFile, theCKID);
- DisposeHandle((Handle)theCKID);
- if (err != noErr) return;
- TaskDone();
- }
-
-
- void DoFileMenu(short itemID)
- {
- if ( itemID == 1 )
- SelectFile(); // call file selection userProc
- else
- SendQuitToSelf(); // send self a 'quit' event
- }
-